package com.iqik.base.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;

public class NIOServer2 extends Thread {

    // 声明多路复用器
    private Selector selector;

    // 读buffer
    private ByteBuffer readBuffer = ByteBuffer.allocate(1024);
    // 写buffer
    private ByteBuffer writeBuffer = ByteBuffer.allocate(1024);

    public NIOServer2(int port){
        init(port);
    }

    private void init(int port) {
        try {
            // 开启多路复用
            this.selector = Selector.open();
            // 开启服务通道
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            // 设置为非阻塞
            serverSocketChannel.configureBlocking(false);
            // 绑定端口
            serverSocketChannel.bind(new InetSocketAddress(port));
            // 注册, 标记服务器连接为ACCEPT
            serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        for (;;) {
            try {
                // 阻塞方法, 当有至少一个通道被选中，执行此方法， 选中一个通道
                this.selector.select();
                // 获取通道中的编号集合
                Iterator<SelectionKey> keys = this.selector.selectedKeys().iterator();
                // 遍历
                while (keys.hasNext()) {
                    SelectionKey key = keys.next();
                    // 当前key 需要从集合中pop，如果不移除，下次循环执行对应的逻辑，回造成业务混乱
                    keys.remove();
                    // 判断通道是否有效
                    if (key.isValid()) {
                        // 判断通道是否可以连接
                        switch (key.interestOps()) {
                            case SelectionKey.OP_ACCEPT:
                                // 可连接 TODO
                                System.out.println("通道是ACCEPT状态");
                            case SelectionKey.OP_READ:
                                // 可读状态 TODO
                                System.out.println("通道是刻度状态状态");
                            case SelectionKey.OP_WRITE:
                                // 可读状态 TODO
                                System.out.println("通道是刻度状态状态");
                            default:
                                System.out.println("默认状态");
                        }
                    }
                }
                //
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
